#include "CGamePlayState.h"

#include "SGD Wrappers/CSGD_Direct3D.h"
#include "SGD Wrappers/CSGD_DirectInput.h"
#include "SGD Wrappers/CSGD_WaveManager.h"

#include "CGame.h"
#include "CMainMenuState.h"
#include "CCamera.h"
#include "CExpOrb.h"
#include "CCrackedWall.h"
#include "CChaseAI.h"
#include "CIdleAI.h"
#include "CBaseAttack.h"
#include "CChargeAI.h"
#include "CComboAI.h"
#include "CVulnerableAI.h"
#include "CLiniarAI.h"
#include "CSummonAI.h"
#include "CMainMenuState.h"
#include "CGauntlet.h"
#include "CCrossBowBolt.h"
#include "CHealthBar.h"
#include "CWorldEngine.h"
#include "CSaveState.h"
#include "CLoadState.h"
#include "CUpgradeState.h"
#include "ComboSystem.h"
#include "CMessageSystem.h"
#include "CEventSystem.h"


#include "CAnimationEngine.h"


CGamePlayState::CGamePlayState(void)
{
	m_nSoundID = -1;
	m_nPauseIndex = 0;
	m_bInversed = false;

	m_BMFonts.SetImageID(CSGD_TextureManager::GetInstance()->LoadTexture("resources/graphics/AnG_bitmapfont.png", D3DXCOLOR(0,255,0,255)));
	m_BMFonts.SetCharWidth(8);
	m_BMFonts.SetCharHeight(9);
	m_BMFonts.SetCol(16);
	m_BMFonts.SetStartChar('@');

	/*savePause = new savePauseMenu();
	savePause->isPaused = false;
	savePause->menuIndex = 0;
	savePause->menuCursor = CSGD_TextureManager::GetInstance()->LoadTexture("Resources/Graphics/SGD_MenuCursor.png", D3DCOLOR_XRGB(255, 255, 255));*/
}
CGamePlayState::~CGamePlayState(void)
{
	delete savePause;
}

CGamePlayState* CGamePlayState::GetInstance(void)
{
	static CGamePlayState instance;
	return &instance;
}

void CGamePlayState::Enter(void)
{
//#ifndef _DEBUG
//
//#else
//	filer.StartTimer();
//#endif
	CSGD_WaveManager* pWM = CSGD_WaveManager::GetInstance();
	CSGD_TextureManager* pTM = CSGD_TextureManager::GetInstance();
	ComboSystem::GetInstance()->InitComboSystem();
	
	m_bPaused = false;
	m_nPauseIndex = 0;

	m_pOF = ObjectFactory<string,CBase>::GetInstance();
	m_pOM = ObjectManager::GetInstance();
	m_pPEngine = ParticleEngine::GetInstance();
	m_pPEngine->Load("resources/Saved Particles/ExpOrb.bin");
	m_pPEngine->Load("resources/Saved Particles/Slash.bin");
	m_pPEngine->Load("resources/Saved Particles/Flame_Thrower.bin");
	m_pPEngine->Load("resources/Saved Particles/Fire_Ball.bin");
	m_pPEngine->Load("resources/Saved Particles/HealthBar.bin");
	m_pPEngine->Load("resources/Saved Particles/ManaBar.bin");


	

	m_pOF->RegisterClassType<CPlayer>("CPlayer");
	m_pOF->RegisterClassType<CEnemy>("CEnemy");
	m_pOF->RegisterClassType<CExpOrb>("CExpOrb");
	m_pOF->RegisterClassType<CCrackedWall>("CCrackedWall");
	m_pOF->RegisterClassType<CInverseBlock>("CInverseBlock");
	m_pOF->RegisterClassType<CGauntlet>("CGauntlet");
	m_pOF->RegisterClassType<CHealthBar>("CHealthBar");
	m_pOF->RegisterClassType<CSavePoint>("CSavePoint");
	m_pOF->RegisterClassType<CCrossBowBolt>("CCrossBowBolt");

	m_player = (CPlayer*)m_pOF->CreateObject("CPlayer");
	m_player->SetPosX( 300 );
	m_player->SetPosY( 3290 );
	m_player->SetPlayerCombos();
	m_pOM->AddObject( m_player );
	m_player->Release();

	/*CCrackedWall* temp_wall1 = (CCrackedWall*)m_pOF->CreateObject("CCrackedWall");
	temp_wall1->SetPosX(100);
	temp_wall1->SetPosY(225);*/

	//CCrackedWall* temp_wall2 = (CCrackedWall*)m_pOF->CreateObject("CCrackedWall");
	//temp_wall2->SetPosX(700);
	//temp_wall2->SetPosY(225);

	//CCrackedWall* temp_wall3 = (CCrackedWall*)m_pOF->CreateObject("CCrackedWall");
	//temp_wall3->SetPosX(100);
	//temp_wall3->SetPosY(475);

	//CCrackedWall* temp_wall4 = (CCrackedWall*)m_pOF->CreateObject("CCrackedWall");
	//temp_wall4->SetPosX(700);
	//temp_wall4->SetPosY(475);

	//temp_wall1->SetConnectedCrack(temp_wall3);
	//temp_wall2->SetConnectedCrack(temp_wall4);
	//temp_wall3->SetConnectedCrack(temp_wall1);
	//temp_wall4->SetConnectedCrack(temp_wall2);

	//temp_wall1->SetPlayer(m_player);
	//temp_wall2->SetPlayer(m_player);
	//temp_wall3->SetPlayer(m_player);
	//temp_wall4->SetPlayer(m_player);

	//m_pOM->AddObject(temp_wall1);
	//m_pOM->AddObject(temp_wall2);
	//m_pOM->AddObject(temp_wall3);
	//m_pOM->AddObject(temp_wall4);
	//temp_wall1->Release();
	//temp_wall2->Release();
	//temp_wall3->Release();
	//temp_wall4->Release();

	//m_pInversBlock1 = (CInverseBlock*)m_pOF->CreateObject("CInverseBlock");
	//m_pInversBlock2 = (CInverseBlock*)m_pOF->CreateObject("CInverseBlock");

	//m_pInversBlock1->SetPosX(100);
	//m_pInversBlock2->SetPosX(400);

	//m_pInversBlock1->SetPosY(300);
	//m_pInversBlock2->SetPosY(300);

	//m_pInversBlock1->SetWidth(64);
	//m_pInversBlock2->SetWidth(256);

	//m_pInversBlock1->SetHeight(256);
	//m_pInversBlock2->SetHeight(64);

	//m_pInversBlock1->SetIsWhite(false);
	//m_pInversBlock2->SetIsWhite(true);

	//m_pInversBlock1->SetIsActive(true);
	//m_pInversBlock2->SetIsActive(false);

	//m_pOM->AddObject(m_pInversBlock1);
	//m_pOM->AddObject(m_pInversBlock2);

	//m_pInversBlock1->Release();
	//m_pInversBlock2->Release();

	CGauntlet* gauntlet = (CGauntlet*)m_pOF->CreateObject("CGauntlet");
	gauntlet->SetPosX(100);
	gauntlet->SetPosY(1550);
	gauntlet->SetWidth(32);
	gauntlet->SetHeight(32);
	m_pOM->AddObject(gauntlet);
	gauntlet->Release();

	CHealthBar* healthbar = (CHealthBar*)m_pOF->CreateObject("CHealthBar");
	healthbar->SetPosX(67);
	healthbar->SetPosY(32);
	healthbar->SetType(0);
	m_pOM->AddObject(healthbar);
	healthbar->Release();

	enemy = (CEnemy*)m_pOF->CreateObject("CEnemy");
	enemy->SetPosX(( float )( rand() % (200) + 100 ));
	enemy->SetPosY(1475);
	enemy->SetWidth( 32 );
	enemy->SetHeight( 64 );

	CIdleAI* temp_idle = new CIdleAI();
	temp_idle->SetOwner(enemy);
	temp_idle->SetPlayer(m_player);
	enemy->LoadAI(temp_idle);

	CChaseAI* temp_chase = new CChaseAI();
	temp_chase->SetOwner(enemy);
	temp_chase->SetPlayer(m_player);
	enemy->LoadAI(temp_chase);

	CChargeAI* temp_charge = new CChargeAI();
	temp_charge->SetOwner(enemy);
	temp_charge->SetPlayer(m_player);
	enemy->LoadAI(temp_charge);

	CComboAI* temp_combo = new CComboAI();
	temp_combo->SetOwner(enemy);
	temp_combo->SetPlayer(m_player);
	enemy->LoadAI(temp_combo);

	CVulnerable* temp_vulnerable = new CVulnerable();
	temp_vulnerable->SetOwner(enemy);
	temp_vulnerable->SetPlayer(m_player);
	enemy->LoadAI(temp_vulnerable);

	CLiniarAI* temp_liniar = new CLiniarAI();
	temp_liniar->SetOwner(enemy);
	temp_liniar->SetPlayer(m_player);
	enemy->LoadAI(temp_liniar);

	CSummonAI* temp_summon = new CSummonAI();
	temp_summon->SetOwner(enemy);
	temp_summon->SetPlayer(m_player);
	enemy->LoadAI(temp_summon);

	/*CChaseAI* temp_chase = new CChaseAI();
	temp_chase->SetOwner(enemy);
	temp_chase->SetPlayer(m_player);
	enemy->LoadAI(temp_chase);*/

	/*CBaseAttackAI* temp_attack = new CBaseAttackAI();
	temp_attack->SetOwner(enemy);
	temp_attack->SetPlayer(m_player);
	enemy->LoadAI(temp_attack);*/

	enemy->SetCurrentAI(AI_IDLE);
	enemy->SetEnemyType(ENE_WARDEN);
	enemy->SetHP( 100 );
	enemy->SetMaxHP( 100 );
	m_pOM->AddObject( enemy );

	//CHealthBar* manabar = (CHealthBar*)m_pOF->CreateObject("CHealthBar");
	//manabar->SetPosX(67);
	//manabar->SetPosY(48);
	//manabar->SetType(1);
	//m_pOM->AddObject(manabar);
	//manabar->Release();

	CCamera::GetInstance()->SetCameraPosX(0);
	CCamera::GetInstance()->SetCameraPosY(0);

	/*savePause->isPaused = false;
	savePause->menuIndex = 0;*/

	CWorldEngine::GetInstance()->LoadMap("resources/Level Data/sewers.bin");
	CWorldEngine::GetInstance()->GetMap()->layerList[ 0 ]->visible = true;
	CWorldEngine::GetInstance()->GetMap()->layerList[ 1 ]->visible = false;
	CWorldEngine::GetInstance()->GetMap()->layerList[ 2 ]->visible = false;

//#ifndef _DEBUG
//
//#else
//	filer.ResultOfTime( "CGamePlayState_Enter" );
//#endif 
}

bool CGamePlayState::Input(void)
{
//#ifndef _DEBUG
//#else
//	filer.StartTimer();
//#endif 
	CSGD_DirectInput* pDI = CSGD_DirectInput::GetInstance();


	if(pDI->KeyPressed(DIK_ESCAPE))
	{
		m_bPaused = !m_bPaused;
	}

	if(!m_bPaused)
	{
		if(pDI->KeyPressed(DIK_1))
		{
			enemy->SetHP(enemy->GetHP()-26);
			/*enemy = (CEnemy*)m_pOF->CreateObject("CEnemy");
			enemy->SetPosX(( float )( rand() % (200) + 100 ));
			enemy->SetPosY(300);
			enemy->SetWidth( 32 );
			enemy->SetHeight( 64 );

			CIdleAI* temp_idle = new CIdleAI();
			temp_idle->SetOwner(enemy);
			temp_idle->SetPlayer(m_player);
			enemy->LoadAI(temp_idle);

			CChaseAI* temp_chase = new CChaseAI();
			temp_chase->SetOwner(enemy);
			temp_chase->SetPlayer(m_player);
			enemy->LoadAI(temp_chase);

			CBaseAttackAI* temp_attack = new CBaseAttackAI();
			temp_attack->SetOwner(enemy);
			temp_attack->SetPlayer(m_player);
			enemy->LoadAI(temp_attack);

			enemy->SetCurrentAI(AI_IDLE);
			enemy->SetEnemyType(ENE_GUARD);
			m_pOM->AddObject( enemy );
			enemy->Release();*/
		}
		if(pDI->KeyPressed(DIK_2))
		{
			CExpOrb* temp_orb = (CExpOrb*)m_pOF->CreateObject("CExpOrb");
			temp_orb->SetPlayer(m_player);
			m_pOM->AddObject(temp_orb);
			temp_orb->Release();
			//ParticleEngine::GetInstance()->AddEffect(0, 100, 300, 300, true);
		}

		if(pDI->KeyPressed(DIK_4))
		{
			m_bInversed = !m_bInversed;
			CWorldEngine::GetInstance()->GetMap()->layerList[ 2 ]->visible = !CWorldEngine::GetInstance()->GetMap()->layerList[ 2 ]->visible ;
			CWorldEngine::GetInstance()->GetMap()->layerList[ 0 ]->visible = !CWorldEngine::GetInstance()->GetMap()->layerList[ 0 ]->visible ;
		}
		if(pDI->KeyPressed(DIK_5))
			m_pPEngine->AddEffect(2, 10000, 300,300,false);

		if(pDI->KeyPressed(DIK_6))
			m_pPEngine->AddEffect(3, 10000, 100,100,false);
		if(pDI->KeyPressed(DIK_7))
		{
			if(m_player->GetGauntlet())
			{
				m_player->SetGauntlet(false);

				CGauntlet* gauntlet = (CGauntlet*)m_pOF->CreateObject("CGauntlet");
				gauntlet->SetPosX(100);
				gauntlet->SetPosY(300);
				gauntlet->SetWidth(32);
				gauntlet->SetHeight(32);
				m_pOM->AddObject(gauntlet);
				gauntlet->Release();
			}
		}
	}
	else if(m_bPaused)
	{
		if(pDI->KeyPressed(DIK_UP))
		{
			if(--m_nPauseIndex < 0)
				m_nPauseIndex = 2;
		}
		else if(pDI->KeyPressed(DIK_DOWN))
			if(++m_nPauseIndex > 2)
				m_nPauseIndex = 0;

		if(pDI->KeyPressed(DIK_RETURN))
		{
			if(m_nPauseIndex == 2)
				CGame::GetInstance()->ChangeState(CMainMenuState::GetInstance());
			else if( m_nPauseIndex == 1 )
				CGame::GetInstance()->ChangeState( CUpgradeState::GetInstance());
			else if(m_nPauseIndex == 0)
				m_bPaused = false;
		}
	}

	
//#ifndef _DEBUG
//#else
//	filer.ResultOfTime( "CGamePlayState_Input" );
//#endif

	return false;
}

void CGamePlayState::Update(float fElapsedTime)
{
//#ifndef _RELEASE
//	filer.StartTimer();
//#endif

	if(!m_bPaused)
	{
		m_pOM->UpdateObjects( fElapsedTime );
		m_pPEngine->Update(fElapsedTime);
		CAnimationEngine::GetInstance()->Update( fElapsedTime );
		m_pOM->CheckCollision();
		CEventSystem::GetInstance()->ProcessEvents();
		CMessageSystem::GetInstance()->ProcessMessages();
	}
//
//#ifndef _RELEASE
//	filer.ResultOfTime( "CGamePlayState_Update" );
//#endif
}

void CGamePlayState::Render(void)
{
//#ifndef _DEBUG
//#else
//	filer.StartTimer();
//#endif 

	CSGD_Direct3D* pD3D = CSGD_Direct3D::GetInstance();

	if(!m_bInversed)
		pD3D->Clear(255, 255, 255);
	else
		pD3D->Clear(0, 0, 0);

	pD3D->DeviceBegin();

	

	pD3D->SpriteBegin();

	
	CWorldEngine::GetInstance()->DrawMap();
	

	m_pPEngine->Render();
	m_pOM->RenderObjects();

	char temp_buffer[255];
	sprintf_s(temp_buffer, sizeof(temp_buffer), "%d", m_player->GetPlayerExp());

	RECT itembox = {31,31,63,63};
	pD3D->DrawRect(itembox, 255,255,255);

	if(!m_bInversed)
	{
		pD3D->DrawText(temp_buffer,60, 70, 0,0,0);
		m_BMFonts.Draw("EXP: ", 32, 75, 1.0f, D3DCOLOR_ARGB(255,0,0,0));
	}
	else
	{
		pD3D->DrawText(temp_buffer,60, 70);
		m_BMFonts.Draw("EXP: ", 32, 75, 1.0f, D3DCOLOR_ARGB(255,255,255,255));
	}

	if(!m_bInversed)
	{
		pD3D->DrawLine(32,32,32,64,0,0,0);
		pD3D->DrawLine(31,64,66,64,0,0,0);
		pD3D->DrawLine(64,64,64,32,0,0,0);
		pD3D->DrawLine(31,32,66,32,0,0,0);
	}
	else
	{
		pD3D->DrawLine(32,32,32,64,255,255,255);
		pD3D->DrawLine(31,64,66,64,255,255,255);
		pD3D->DrawLine(64,64,64,32,255,255,255);
		pD3D->DrawLine(31,32,66,32,255,255,255);
	}

	if(m_player->GetGauntlet())
		CSGD_TextureManager::GetInstance()->Draw(CSGD_TextureManager::GetInstance()->LoadTexture("resources/graphics/Fist.png",D3DCOLOR_ARGB(255,255,255,255)), 36,36, 0.8f, 0.8f);

	if(m_bPaused)
	{
		RECT temprect = {0,0,640,480};
		CSGD_TextureManager::GetInstance()->Draw(CSGD_TextureManager::GetInstance()->LoadTexture("resources/graphics/AnG_pauseoverlay.png"),
			0,0, 1.0f, 1.0f, &temprect, 0.0f, 0.0f, 0.0f, D3DCOLOR_ARGB(100,255,255,255));
		CSGD_TextureManager::GetInstance()->Draw(CSGD_TextureManager::GetInstance()->LoadTexture("Resources/Graphics/SGD_MenuCursor.png", D3DCOLOR_XRGB(255, 255, 255))
		, 80, 100+( 100 * m_nPauseIndex));

		if(m_bPaused)
		{
			m_BMFonts.Draw("RESUME", 100, 100, 1.0f,D3DXCOLOR(255,255,255,255));
			m_BMFonts.Draw("UPGRADE", 100, 200, 1.0f, D3DXCOLOR(255,255,255,255));
			m_BMFonts.Draw("EXIT", 100, 300 , 1.0f, D3DXCOLOR(255,255,255,255));
		}
	}

	pD3D->SpriteEnd();

	//Health Bar
	//RECT healthbar = {67, 32, 128, 48}; 
	//pD3D->DrawRect(healthbar, 255,0,0);

	pD3D->DeviceEnd();

	pD3D->Present();

//#ifndef _DEBUG
//#else
//	filer.ResultOfTime( "CGamePlayState_Render" );
//#endif
}

void CGamePlayState::Exit(void)
{
//#ifndef _DEBUG
//#else
//	filer.StartTimer();
//#endif
	m_nPauseIndex = 0;
	CWorldEngine::GetInstance()->UnLoadMap();
	ComboSystem::GetInstance()->ShutdownComboSystem();
	m_pOM->RemoveAllObjects();
	m_pOM->DeleteInstance();
	enemy->Release();

//#ifndef _DEBUG
//#else
//	filer.ResultOfTime( "CGamePlayState_Exit" );
//	filer.SaveResults();
//#endif
}